public class Channel
{

	private boolean shoutAllowedToLeave;
	private boolean askAllowedToLeave;
	
	private int askWaiting;
	private int shoutWaiting;
	
	public Channel()
	{
		shoutAllowedToLeave = false;
		askAllowedToLeave = false;
		
		askWaiting = 0;
		shoutWaiting = 0;
	}
	
	public synchronized int getAskCount()
	{
		return askWaiting;
	}
	
	public synchronized int getShoutCount()
	{
		return shoutWaiting;
	}
	
	public synchronized void shout()
	{	
		if(askWaiting > 0)
		{
			askAllowedToLeave = true;
			notify();
		}
		else
		{
			shoutWaiting++;
			
			while(!shoutAllowedToLeave)
			{
				while(true)
				{
					try {
						wait();
						break;
					} catch (InterruptedException e) {}
				}
			}
			
			shoutAllowedToLeave = false;
			shoutWaiting--;
		}
	}
	
	public synchronized void ask()
	{	
		if(shoutWaiting > 0)
		{
			shoutAllowedToLeave = true;
			notify();
		}
		else
		{
			askWaiting++;
			
			while(!askAllowedToLeave)
			{
				while(true)
				{
					try {
						wait();
						break;
					} catch (InterruptedException e) {}
				}
			}
			
			askAllowedToLeave = false;
			askWaiting--;
		}
	}
}